#include <map>
#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <sys/time.h>
#include <sstream>


std::map<std::string, int> map;
int n = 1000000;
pthread_mutex_t mutex;
pthread_rwlock_t rwmutex;



void lock(){

    //pthread_mutex_lock(&mutex);
pthread_rwlock_rdlock(&rwmutex); 
}

void unlock() {
//    pthread_mutex_unlock(&mutex);
     pthread_rwlock_unlock(&rwmutex);
}


typedef void*(THREADFUNC) (void *arg);
    
int64_t startThread(THREADFUNC* func, void* arg) {
    pthread_t thread_id = -1;
    pthread_create(&thread_id, NULL, func, arg);

    return thread_id;
}

int waitThread(pthread_t thread_id) {
    int ret = pthread_join(thread_id, NULL);
    return ret;
}

uint64_t nowMicros() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
}

void* thread_func(void* arg) {
 
   int match = 0, unmatch = 0;

    uint64_t start = nowMicros();

    for(int i = 0; i < n; ++i) {
        lock();
        std::ostringstream oss; oss<<"partiotion"<<i;
        if(map.count(oss.str())) ++match;
        else ++unmatch;
        unlock();
    }

    uint64_t end = nowMicros();
    std::cout<<(end-start)<<"\n";

    return NULL;
}

void startThreads(int n) {
    pthread_t id[128];
    for(int i = 0; i < n; ++i) {
        id[i] = startThread(thread_func, NULL);
    }

    for(int i = 0; i < n; ++i) {
        waitThread(id[i]);
    }
    
    std::cout<<"done\n";
    exit(0);
}


int main() {
    for(int i = 0; i < 8; ++i) {
        std::ostringstream oss; oss<<"partiotion"<<i;
        map[oss.str()] = i;
    }

    pthread_mutex_init(&mutex, NULL);
    pthread_rwlock_init(&rwmutex, NULL);
    startThreads(1);

    sleep(100000000);
}


